<!doctype html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Live2D + PIXI（无 Vue）</title>
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <style>
      html, body {
        margin: 0;
        padding: 0;
        height: 100%;
        background: #f1e6aa;
      }
      #stage {
        position: fixed;
        inset: 0;
        /* width: 100vw; */
        /* height: 100vh; */
        display: block;
      }
      .controls {
        position: fixed;
        bottom: 20px;
        left: 50%;
        transform: translateX(-50%);
        display: flex;
        gap: 10px;
        z-index: 1000;
      }
      .controls button {
        padding: 10px 20px;
        background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        color: #fff;
        border: none;
        border-radius: 25px;
        cursor: pointer;
        font-size: 14px;
        font-weight: 500;
        transition: all 0.3s ease;
        box-shadow: 0 4px 15px rgba(0,0,0,0.2);
      }
      .controls button:hover {
        transform: translateY(-2px);
        box-shadow: 0 6px 20px rgba(0,0,0,0.3);
      }
      .controls button:active {
        transform: translateY(0);
        box-shadow: 0 2px 10px rgba(0,0,0,0.2);
      }
    </style>
  </head>
  <body>
    <canvas id="stage"></canvas>
    <div class="controls">
      <button id="btn-toggle">开始说话</button>
      <button id="btn-hello">说“你好”</button>
      <button id="btn-stop">闭嘴</button>
      <button id="btn-flickup">动作 FlickUp</button>
    </div>

    <!-- Live2D Cubism Core -->
    <script src="public/live2dcubismcore.min.js"></script>

    <!-- PIXI.js -->
    <script src="public/pixi.js"></script>
    <!-- pixi-live2d-display UMD 构建 -->
    <script src="public/cubism4.min.js"></script>

    <script>
      (async function () {
        const canvas = document.getElementById('stage');

        const app = new PIXI.Application({
          view: canvas,
          height: window.innerHeight,
          width: window.innerWidth,
          resolution: window.devicePixelRatio,
          autoDensity: true,
          antialias: true,
          backgroundAlpha: 0,
        });

        // 供内部使用
        window.PIXI = PIXI;

        // === Mouth animation controls (参考 App.vue 的 animateMouth) ===
        let model = null;
        let modelLoaded = false;
        let isTalking = false;
        let mouthAnimationId = null;
        const mouthParam = 'ParamMouthOpenY';
        const mouthSpeed = 0.01; // 数值越小越慢
        const talkingDuration = 2000; // 说“你好”持续时间

        function animateMouth() {

          if (!isTalking || !modelLoaded || !model) return;
          const internal = model.internalModel;
          if (internal && internal.coreModel) {
            const coreModel = internal.coreModel;
            const time = Date.now() * mouthSpeed;
            const mouthValue = Math.abs(Math.sin(time)) * 0.5; // 0-0.5
            coreModel.setParameterValueById(mouthParam, mouthValue);
            coreModel.update();
          }
          mouthAnimationId = requestAnimationFrame(animateMouth);
        }

        function startTalking() {
          if (isTalking || !modelLoaded || !model) return;
          isTalking = true;
          animateMouth();
          updateToggleText();
        }

        function stopTalking() {
          isTalking = false;
          if (mouthAnimationId) {
            cancelAnimationFrame(mouthAnimationId);
            mouthAnimationId = null;
          }
          if (modelLoaded && model?.internalModel?.coreModel) {
            const coreModel = model.internalModel.coreModel;
            coreModel.setParameterValueById(mouthParam, 0);
            coreModel.update();
          }
          updateToggleText();
        }

        function sayHello() {
          startTalking();
          setTimeout(stopTalking, talkingDuration);
        }

        // 绑定按钮（不依赖模型是否加载成功）
        const btnToggle = document.getElementById('btn-toggle');
        const btnHello = document.getElementById('btn-hello');
        const btnStop = document.getElementById('btn-stop');
        const btnFlickUp = document.getElementById('btn-flickup');

        function updateToggleText() {
          if (!btnToggle) return;
          btnToggle.textContent = isTalking ? '停止说话' : '开始说话';
        }

        btnToggle?.addEventListener('click', () => {
          if (isTalking) {
            stopTalking();
          } else {
            startTalking();
          }
        });
        btnHello?.addEventListener('click', sayHello);
        btnStop?.addEventListener('click', stopTalking);
        btnFlickUp?.addEventListener('click', () => {
          if (!modelLoaded || !model) return;
          if (typeof model.motion === 'function') {
            model.motion('FlickUp');
            console.log('新版本 API');
          } else if (model?.internalModel?.motionManager?.startMotion) {
            // 兼容旧版本 API
            console.log('兼容旧版本 API');
            model.internalModel.motionManager.startMotion('FlickUp', 0, 2);
          }
        });

        try {
          // 选择一个现有模型（可换成 shizuku 或 mao_pro）
          model = await PIXI.live2d.Live2DModel.from('public/hiyori_pro_zh/runtime/hiyori_pro_t11.model3.json');
          app.stage.addChild(model);
          model.scale.set(0.3);
          model.x = (window.innerWidth  - model.width) * 0.5;
          modelLoaded = true;

        } catch (err) {
          console.error('加载 Live2D 模型失败:', err);
        }
      })();
    </script>
  </body>
</html>
